#include "matrix.h"
#include "types.h"

#include <assert.h>

void byte_matrix_mul(
	const byte* lhs, 
	int lhs_rows,
	int lhs_cols,
	const byte* rhs,
	int rhs_rows,
	int rhs_cols,
	byte* result,
	int result_size,
	byte (*add_func)(byte,byte),
	byte (*mul_func)(byte,byte)
)
{
	assert(lhs_cols == rhs_rows);
	assert(result_size >= lhs_rows * rhs_cols);

	int i,j,k;
	byte tmp;
	for( i = 0; i < lhs_rows; ++i)
	{
		for(j = 0; j < rhs_cols; ++j)
		{
			tmp = mul_func( lhs[i*lhs_cols + 0], rhs[0*rhs_cols + j] );
			for( k = 1; k < lhs_cols; ++k)
			{
				tmp = add_func(tmp, mul_func( lhs[i*lhs_cols+k], rhs[k*rhs_cols+j]));
			}
			result[i*rhs_cols+j] = tmp;
		}
	}
}


#include <stdio.h>
byte add_op(byte lhs, byte rhs)
{
	return lhs + rhs;
}
byte mul_op(byte lhs, byte rhs)
{
	return lhs * rhs;
}
void test_byte_matrix_mul()
{

	printf("Start testing byte_matrix_mul...........\n");
	byte lhs[16] = {
		1,2,3,4,
		5,6,7,8,
		5,6,7,8,
		5,6,7,8,
	};

	byte rhs[16] = {
		1,2,3,4,
		5,6,7,8,
		5,6,7,8,
		5,6,7,8,
	};
	
	byte result[16];
	byte realResult[16] = {
		46, 56, 66, 76,
		110, 136, 162, 188,
		110, 136, 162, 188,
		110, 136, 162, 188,
	};

	int i;
	byte_matrix_mul(lhs, 4 ,4, rhs, 4, 4, result, 16, add_op, mul_op);
	for( i = 0; i < 16; ++i)
	{
		assert( realResult[i] == result[i]);
	}

	printf("Test byte_matrix_mul complete!\n");
}
